package com.lalameow.packet.packImpl;


import com.lalameow.packet.BasePack;
import com.lalameow.packet.enumtype.PackType;
import com.lalameow.packet.enumtype.VailPlayerState;
import com.lalameow.packet.pojo.MdsInfo;
import com.lalameow.packet.pojo.AuthenticateClient;
import com.lalameow.serverlogingate.LogingateApplication;
import com.lalameow.serverlogingate.enetiy.PlayerInfo;
import com.lalameow.serverlogingate.exception.AccountException;
import com.lalameow.serverlogingate.network.ClientManager;
import com.lalameow.serverlogingate.service.GameServerInfoService;
import com.lalameow.serverlogingate.service.PlayerInfoService;
import com.lalameow.serverlogingate.utiles.ApplicationContextUtil;
import com.lalameow.serverlogingate.utiles.ModUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.SocketChannel;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * 创建人: 陈刚
 * 日期: 2018/2/26
 * 时间: 9:52
 * 功能：请进行修改
 */
@Slf4j
@Data
public class LoginPack extends PacketAbstract {
    private String userName;
    private String password;
    private MdsInfo[] mdsInfos;




    @Override
    public BasePack revice(ChannelHandlerContext ctx) {
        PlayerInfoService playerInfoService=(PlayerInfoService) ApplicationContextUtil.getContext().getBean("playerInfoService");
        BasePack basePack=new BasePack();
        basePack.setPackType(PackType.LOGINRECIVE);
        LoginRecivePack loginRecivePack=new LoginRecivePack();
        PlayerInfo playerInfo=playerInfoService.findByUserNameAndPwd(this.userName.trim(),this.password.trim());
        try {
          if(checkAccount(playerInfo)){
              loginRecivePack.setLogin(true);
              loginRecivePack.setPlayerName(playerInfo.getPlayerName());
              loginRecivePack.setServerInfoArray(GameServerInfoService.serverInfos);
              //更新玩家登陆IP和时间
              playerInfo.setLastLoginIp(ctx.channel().remoteAddress().toString());
              playerInfo.setLastLoginTime(new Date());
              playerInfoService.save(playerInfo);

              // 生成随机UUID

              //设置公钥
              basePack.setKey(LogingateApplication.publicKey);
              AuthenticateClient authClient=new AuthenticateClient();
              authClient.setPlayerName(playerInfo.getPlayerName());
              authClient.setRandomKey(ModUtils.getRandomKey());
              basePack.setClientId(authClient.toString());
              ClientManager.instanss.getPlayerCache().put(playerInfo.getPlayerName(), VailPlayerState.NOAUTH);
              log.info("玩家{}成功登陆服务器!",playerInfo.getPlayerName());
          }
        } catch (AccountException e) {
            loginRecivePack.setLogin(false);
            loginRecivePack.setMsg("§c"+e.getMessage());
        }
        basePack.setBodyContent(loginRecivePack.toJsonStr());
        return basePack;
    }
    private boolean checkAccount(PlayerInfo playerInfo) throws AccountException {
        if(playerInfo==null){
            throw new AccountException("账号或密码错误！");
        }
        if(playerInfo.isLocked()){
            throw new AccountException("账号已经被锁定，请联系管理员！");
        }
        if(invalidMods(playerInfo)){
            throw new AccountException("账号未通过安全检查，请勿增删mod！");
        }
        if(playerInfo.getPlayerName()==null){
            throw new AccountException("非法游戏名称！");
        }
        if(playerInfo.getPlayerName().length()<2){
            throw new AccountException("非法游戏名称！");
        }
        return true;
    }

    /**
     * 校验是否有无效的mod
     * @param playerInfo
     * @return true 为有无效mod，false没有无效的MOD
     */
    private boolean invalidMods(PlayerInfo playerInfo){
        if(playerInfo.isHasAdmin()){
            return false;
        }
        if(playerInfo.isPassCheat()){
            return false;
        }
        if(this.mdsInfos==null){
            return false;
        }
        ModUtils modUtils=(ModUtils) ApplicationContextUtil.getContext().getBean("modUtils");
        boolean flag=true;
        for (MdsInfo mdsInfo : mdsInfos) {
            if(modUtils.vaildMod(mdsInfo)){
                flag= false;
            }else {
                flag=true;
                break;
            }
        }
        return flag;
    }
}
